--[[
从长度为m的数组中选n个元素的组合

组合算法   
  本程序的思路是开一个数组，其下标表示1到m个数，数组元素的值为1表示其下标  
  代表的数被选中，为0则没选中。     
  首先初始化，将数组前n个元素置1，表示第一个组合为前n个数。     
  然后从左到右扫描数组元素值的“10”组合，找到第一个“10”组合后将其变为   
  “01”组合，同时将其左边的所有“1”全部移动到数组的最左端。     
  当第一个“1”移动到数组的m-n的位置，即n个“1”全部移动到最右端时，就得   
  到了最后一个组合。     
  例如求5中选3的组合：     
  1   1   1   0   0   //1,2,3     
  1   1   0   1   0   //1,2,4     
  1   0   1   1   0   //1,3,4     
  0   1   1   1   0   //2,3,4     
  1   1   0   0   1   //1,2,5     
  1   0   1   0   1   //1,3,5     
  0   1   1   0   1   //2,3,5     
  1   0   0   1   1   //1,4,5     
  0   1   0   1   1   //2,4,5     
  0   0   1   1   1   //3,4,5  

--]]

require("functions")

local comm = {}
function comm.zuhe(atable, n)
    if n > #atable then
        return {}
    end

    local len = #atable
    local meta = {}
    -- init meta data
    for i=1, len do
        if i <= n then
            table.insert(meta,1)
        else
            table.insert(meta,0)
        end
    end

    local result = {}

    -- 记录一次组合
    local tmp = {}
    for i=1, len do
        if meta[i] == 1 then
            table.insert(tmp, atable[i])
        end
    end
    table.insert(result, tmp)

    while true do
        -- 前面连续的0
        local zero_count = 0
        for i=1, len-n do
            if meta[i] == 0 then
                zero_count = zero_count + 1
            else
                break
            end
        end
        -- 前m-n位都是0，说明处理结束
        if zero_count == len-n then
            break
        end

        local idx
        for j=1, len-1 do
            -- 10 交换为 01
            if meta[j]==1 and meta[j+1] == 0 then
                meta[j], meta[j+1] = meta[j+1], meta[j]
                idx = j
                break
            end
        end
        -- 将idx左边所有的1移到最左边
        local k = idx-1
        local count = 0
        while count <= k do
            for i=k, 2, -1 do
                if meta[i] == 1 then
                    meta[i], meta[i-1] = meta[i-1], meta[i]
                end
            end
            count = count + 1
        end

        -- 记录一次组合
        local tmp = {}
        for i=1, len do
            if meta[i] == 1 then
                table.insert(tmp, atable[i])
            end
        end
        table.insert(result, tmp)
    end

    return result
end

local res = comm.zuhe({4,3,2,1,6,9,10,22,34,55,36,86},10)
dump(res)

local string_concat = {"string", "int", "char", "float", "double"}
local _tempStore_string = table.concat(string_concat,":");
print(_tempStore_string)
